#include "ASEntityAttribute.h"

NS_AS_BEGIN

ASEntityAttribute::ASEntityAttribute(unsigned int attrINum,unsigned int attrFNum,unsigned int encryptkey):
_pAttrsI(nullptr),
_pAttrsF(nullptr),
_pAttrsSignI(nullptr),
_pAttrsSignF(nullptr),
_nAttrINum(0),
_nAttrFNum(0),
_encryptkey(encryptkey)
{
	setAttrINum(attrINum);
	setAttrFNum(attrFNum);
	//if(_nAttrINum)
	//{
	//	_pAttrsI = new int[attrINum];
	//	_pAttrsSignI = new int[attrINum];
	//	for (unsigned int i = 0; i < _nAttrINum; i++)
	//	{
	//		setAttributeI(i,0);
	//	}
	//}
	//if(_nAttrFNum)
	//{
	//	_pAttrsF = new float[attrFNum];
	//	_pAttrsSignF = new float[attrFNum];
	//	for (unsigned int i = 0; i < _nAttrINum; i++)
	//	{
	//		setAttributeF(i,0.0f);
	//	}
	//}
}

void ASEntityAttribute::setAttrINum(unsigned int attrINum)
{
	int nOldSize = _nAttrINum;
	int* pOldData = _pAttrsI;
	int* pOldDataSign = _pAttrsSignI;
	_nAttrINum = attrINum;
	if(attrINum>0)
	{
		_pAttrsI = new int[attrINum];
		_pAttrsSignI = new int[attrINum];
		int copySize = nOldSize<attrINum?nOldSize:attrINum;
		if(copySize>0)
		{//keep old value
			if(pOldData)
				memcpy(_pAttrsI,pOldData,sizeof(int)*copySize);
			if(pOldDataSign)
				memcpy(_pAttrsSignI,pOldDataSign,sizeof(int)*copySize);
		}
		for (unsigned int i = copySize; i < attrINum; i++)
		{//set default value
			setAttributeI(i,i<nOldSize?getAttributeI(i):0);
		}
	}
	else
	{
		_pAttrsI = nullptr;
		_pAttrsSignI = nullptr;
	}
	if (pOldData)
		delete[] pOldData;
	if(pOldDataSign)
		delete[] pOldDataSign;
}
void ASEntityAttribute::setAttrFNum(unsigned int attrFNum)
{
	int nOldSize = _nAttrFNum;
	float* pOldData = _pAttrsF;
	float* pOldDataSign = _pAttrsSignF;
	_nAttrFNum = attrFNum;
	if (attrFNum>0)
	{
		_pAttrsF = new float[attrFNum];
		_pAttrsSignF = new float[attrFNum];
		int copySize = nOldSize<attrFNum?nOldSize:attrFNum;
		if(copySize>0)
		{//keep old value
			if(pOldData)
				memcpy(_pAttrsF,pOldData,sizeof(float)*copySize);
			if(pOldDataSign)
				memcpy(_pAttrsSignF,pOldDataSign,sizeof(float)*copySize);
		}
		for (unsigned int i = copySize; i < attrFNum; i++)
		{//set default value
			setAttributeF(i,i<nOldSize?getAttributeF(i):0.0f);
		}
	}
	else
	{
		_pAttrsF = nullptr;
		_pAttrsSignF = nullptr;
	}
	if (pOldData)
		delete[] pOldData;
	if(pOldDataSign)
		delete[] pOldDataSign;
}
void ASEntityAttribute::setEncryptKey(unsigned int encryptkey)
{
	int oldEncryptKey = _encryptkey;
	for (unsigned int i = 0; i < _nAttrINum; i++)
	{
		_encryptkey = oldEncryptKey;
		int oldValue = getAttributeI(i);
		_encryptkey = encryptkey;
		setAttributeI(i,oldValue);
	}
	for (unsigned int i = 0; i < _nAttrFNum; i++)
	{
		_encryptkey = oldEncryptKey;
		float oldValue = getAttributeF(i);
		_encryptkey = encryptkey;
		setAttributeF(i,oldValue);
	}
	_encryptkey = encryptkey;
}

ASEntityAttribute::~ASEntityAttribute()
{
	if(_pAttrsF)
		delete[] _pAttrsF;
	if(_pAttrsSignF)
		delete[] _pAttrsSignF;
	if (_pAttrsI)
		delete[] _pAttrsI;
	if(_pAttrsSignI)
		delete[] _pAttrsSignI;
}

ASEntityAttribute::ASEntityAttribute(const ASEntityAttribute& copy)
{
	memcpy(this,&copy,sizeof(ASEntityAttribute));
	////////////////////////////////
	//dont call this, it will call operate = ;
	//*this = copy;
	///////////////////////////////
	if(copy._pAttrsF)
	{
		_pAttrsF = new float[copy._nAttrFNum];
		memcpy(_pAttrsF,copy._pAttrsF,sizeof(float)*copy._nAttrFNum);
	}
	if(copy._pAttrsSignF)
	{
		_pAttrsSignF = new float[copy._nAttrFNum];
		memcpy(_pAttrsSignF,copy._pAttrsSignF,sizeof(float)*copy._nAttrFNum);
	}
	if (copy._pAttrsI)
	{
		_pAttrsI = new int[copy._nAttrINum];
		memcpy(_pAttrsI,copy._pAttrsI,sizeof(int)*copy._nAttrINum);
	}
	if(copy._pAttrsSignI)
	{
		_pAttrsSignI = new int[copy._nAttrINum];
		memcpy(_pAttrsSignI,copy._pAttrsSignI,sizeof(int)*copy._nAttrINum);
	}
	
}

ASEntityAttribute& ASEntityAttribute::operator=(const ASEntityAttribute& copy)
{
	if(_pAttrsF)
		delete[] _pAttrsF;
	if(_pAttrsSignF)
		delete[] _pAttrsSignF;
	if (_pAttrsI)
		delete[] _pAttrsI;
	if(_pAttrsSignI)
		delete[] _pAttrsSignI;
	memcpy(this,&copy,sizeof(ASEntityAttribute));
	////////////////////////////////
	//dont call this, it will call operate = ;
	//*this = copy;
	///////////////////////////////
	if(copy._pAttrsF)
	{
		_pAttrsF = new float[copy._nAttrFNum];
		memcpy(_pAttrsF,copy._pAttrsF,sizeof(float)*copy._nAttrFNum);
	}
	if(copy._pAttrsSignF)
	{
		_pAttrsSignF = new float[copy._nAttrFNum];
		memcpy(_pAttrsSignF,copy._pAttrsSignF,sizeof(float)*copy._nAttrFNum);
	}
	if (copy._pAttrsI)
	{
		_pAttrsI = new int[copy._nAttrINum];
		memcpy(_pAttrsI,copy._pAttrsI,sizeof(int)*copy._nAttrINum);
	}
	if(copy._pAttrsSignI)
	{
		_pAttrsSignI = new int[copy._nAttrINum];
		memcpy(_pAttrsSignI,copy._pAttrsSignI,sizeof(int)*copy._nAttrINum);
	}
	return *this;
}

int ASEntityAttribute::getAttributeI(unsigned int index)
{
	if (index<_nAttrINum)
	{
		return _pAttrsI[index]^_encryptkey;
	}
	ASLog("ASEntityAttribute::getAttributeI index:%d,maxsize:%d",index,_nAttrINum);
	ASAssert(0,"");
	return 0;
}
void ASEntityAttribute::setAttributeI(unsigned int index,int value)
{
	if (index<_nAttrINum)
	{
		_pAttrsI[index] = value^_encryptkey;
		_pAttrsSignI[index] = value;
		return;
	}
	ASLog("ASEntityAttribute::setAttributeI index:%d,maxsize:%d",index,_nAttrINum);
	ASAssert(0,"");
}
void ASEntityAttribute::changeAttributeI(unsigned int index,int value)
{
	setAttributeI(index,getAttributeI(index)+value);
}
ASEntityAttribute::LimitTriggerEnum ASEntityAttribute::changeAttributeI(unsigned int index,int value,int min,int max,int* pOutValue)
{
	LimitTriggerEnum retEnum = LimitTrigger_NO;
	int oldvalue = getAttributeI(index);
	int newvalue = oldvalue + value;
	if(newvalue<min)
	{
		newvalue = min;
		retEnum = LimitTrigger_MIN;
	}
	else if(newvalue>max)
	{
		newvalue = max;
		retEnum = LimitTrigger_MAX;
	}
	if (pOutValue)
	{
		*pOutValue = newvalue - oldvalue;
	}
	setAttributeI(index,newvalue);
	return retEnum;
}

bool ASEntityAttribute::checkAttributeValidI(unsigned int index)
{
	return getAttributeI(index)!=_pAttrsSignI[index];
}

float ASEntityAttribute::getAttributeF(unsigned int index)
{
	if (index<_nAttrFNum)
	{
		int* pInt =(int*)&_pAttrsF[index];
		int iVal = (*pInt)^_encryptkey;
		return *((float*)&iVal);
	}
	ASLog("ASEntityAttribute::getAttributeF index:%d,maxsize:%d",index,_nAttrFNum);
	ASAssert(0,"");
	return 0.0;
}
void ASEntityAttribute::setAttributeF(unsigned int index,float value)
{
	if (index<_nAttrFNum)
	{
		int* pInt = (int*)&value;
		int iVal = (*pInt)^_encryptkey;
		_pAttrsF[index] = *((float*)&iVal);
		_pAttrsSignF[index] = value;
		return;
	}
	ASLog("ASEntityAttribute::setAttributeF index:%d,maxsize:%d",index,_nAttrFNum);
	ASAssert(0,"");
}
void ASEntityAttribute::changeAttributeF(unsigned int index,float value)
{
	setAttributeF(index,getAttributeF(index)+value);
}
ASEntityAttribute::LimitTriggerEnum ASEntityAttribute::changeAttributeF(unsigned int index,float value,float min,float max,float* pOutValue)
{
	LimitTriggerEnum retEnum = LimitTrigger_NO;
	float oldvalue = getAttributeF(index);
	float newvalue = oldvalue + value;
	if(newvalue<min)
	{
		newvalue = min;
		retEnum = LimitTrigger_MIN;
	}
	else if(newvalue>max)
	{
		newvalue = max;
		retEnum = LimitTrigger_MAX;
	}
	if (pOutValue)
	{
		*pOutValue = newvalue - oldvalue;
	}
	setAttributeF(index,newvalue);
	return retEnum;
}

bool ASEntityAttribute::checkAttributeValidF(unsigned int index)
{
	return getAttributeF(index)!=_pAttrsSignF[index];
}

bool ASEntityAttribute::checkAttributeValid()
{
	for (unsigned int i = 0; i < _nAttrINum; i++)
	{
		if(checkAttributeValidI(i))
			return false;
	}
	for (unsigned int i = 0; i < _nAttrFNum; i++)
	{
		if(checkAttributeValidF(i))
			return false;
	}
	return true;
}

NS_AS_END